package com.zhtools.wx.bean;

import com.zhtools.wx.constants.WXPayConstants;
import com.zhtools.wx.exception.WXPayException;
import com.zhtools.wx.utils.WXPayUtil;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author zhanghao
 * 查询订单响应实体
 */
public class OrderQueryResponse implements Serializable {
    private static final long serialVersionUID = 8240370320112156507L;

    private String returnCode;
    private String returnMsg;
    private String appId;
    private String mchId;
    private String nonceStr;
    private String sign;
    private String resultCode;
    private String errCode;
    private String errCodeDes;
    private String deviceInfo;
    private String openId;
    private String isSubscribe;
    private String tradeType;
    private String tradeState;
    private String bankType;
    private Integer totalFee;
    private Integer settlementTotalFee;
    private String feeType;
    private Integer cashFee;
    private String cashFeeType;
    private Integer couponFee;
    private Integer couponCount;
    private List<Coupon> coupons;
    private String transactionId;
    private String outTradeNo;
    private String attach;
    private String timeEnd;
    private String tradeStateDesc;

    public OrderQueryResponse() {
    }

    public String getReturnCode() {
        return returnCode;
    }

    public void setReturnCode(String returnCode) {
        this.returnCode = returnCode;
    }

    public String getReturnMsg() {
        return returnMsg;
    }

    public void setReturnMsg(String returnMsg) {
        this.returnMsg = returnMsg;
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getMchId() {
        return mchId;
    }

    public void setMchId(String mchId) {
        this.mchId = mchId;
    }

    public String getNonceStr() {
        return nonceStr;
    }

    public void setNonceStr(String nonceStr) {
        this.nonceStr = nonceStr;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getResultCode() {
        return resultCode;
    }

    public void setResultCode(String resultCode) {
        this.resultCode = resultCode;
    }

    public String getErrCode() {
        return errCode;
    }

    public void setErrCode(String errCode) {
        this.errCode = errCode;
    }

    public String getErrCodeDes() {
        return errCodeDes;
    }

    public void setErrCodeDes(String errCodeDes) {
        this.errCodeDes = errCodeDes;
    }

    public String getDeviceInfo() {
        return deviceInfo;
    }

    public void setDeviceInfo(String deviceInfo) {
        this.deviceInfo = deviceInfo;
    }

    public String getOpenId() {
        return openId;
    }

    public void setOpenId(String openId) {
        this.openId = openId;
    }

    public String getIsSubscribe() {
        return isSubscribe;
    }

    public void setIsSubscribe(String isSubscribe) {
        this.isSubscribe = isSubscribe;
    }

    public String getTradeType() {
        return tradeType;
    }

    public void setTradeType(String tradeType) {
        this.tradeType = tradeType;
    }

    public String getTradeState() {
        return tradeState;
    }

    public void setTradeState(String tradeState) {
        this.tradeState = tradeState;
    }

    public String getBankType() {
        return bankType;
    }

    public void setBankType(String bankType) {
        this.bankType = bankType;
    }

    public Integer getTotalFee() {
        return totalFee;
    }

    public void setTotalFee(Integer totalFee) {
        this.totalFee = totalFee;
    }

    public Integer getSettlementTotalFee() {
        return settlementTotalFee;
    }

    public void setSettlementTotalFee(Integer settlementTotalFee) {
        this.settlementTotalFee = settlementTotalFee;
    }

    public String getFeeType() {
        return feeType;
    }

    public void setFeeType(String feeType) {
        this.feeType = feeType;
    }

    public Integer getCashFee() {
        return cashFee;
    }

    public void setCashFee(Integer cashFee) {
        this.cashFee = cashFee;
    }

    public String getCashFeeType() {
        return cashFeeType;
    }

    public void setCashFeeType(String cashFeeType) {
        this.cashFeeType = cashFeeType;
    }

    public Integer getCouponFee() {
        return couponFee;
    }

    public void setCouponFee(Integer couponFee) {
        this.couponFee = couponFee;
    }

    public Integer getCouponCount() {
        return couponCount;
    }

    public void setCouponCount(Integer couponCount) {
        this.couponCount = couponCount;
    }

    public List<Coupon> getCoupons() {
        return coupons;
    }

    public void setCoupons(List<Coupon> coupons) {
        this.coupons = coupons;
    }

    public String getTransactionId() {
        return transactionId;
    }

    public void setTransactionId(String transactionId) {
        this.transactionId = transactionId;
    }

    public String getOutTradeNo() {
        return outTradeNo;
    }

    public void setOutTradeNo(String outTradeNo) {
        this.outTradeNo = outTradeNo;
    }

    public String getAttach() {
        return attach;
    }

    public void setAttach(String attach) {
        this.attach = attach;
    }

    public String getTimeEnd() {
        return timeEnd;
    }

    public void setTimeEnd(String timeEnd) {
        this.timeEnd = timeEnd;
    }

    public String getTradeStateDesc() {
        return tradeStateDesc;
    }

    public void setTradeStateDesc(String tradeStateDesc) {
        this.tradeStateDesc = tradeStateDesc;
    }

    @Override
    public String toString() {
        return "OrderQueryResponse{" +
                "returnCode='" + returnCode + '\'' +
                ", returnMsg='" + returnMsg + '\'' +
                ", appId='" + appId + '\'' +
                ", mchId='" + mchId + '\'' +
                ", nonceStr='" + nonceStr + '\'' +
                ", sign='" + sign + '\'' +
                ", resultCode='" + resultCode + '\'' +
                ", errCode='" + errCode + '\'' +
                ", errCodeDes='" + errCodeDes + '\'' +
                ", deviceInfo='" + deviceInfo + '\'' +
                ", openId='" + openId + '\'' +
                ", isSubscribe='" + isSubscribe + '\'' +
                ", tradeType='" + tradeType + '\'' +
                ", tradeState='" + tradeState + '\'' +
                ", bankType='" + bankType + '\'' +
                ", totalFee=" + totalFee +
                ", settlementTotalFee=" + settlementTotalFee +
                ", feeType='" + feeType + '\'' +
                ", cashFee=" + cashFee +
                ", cashFeeType='" + cashFeeType + '\'' +
                ", couponFee=" + couponFee +
                ", couponCount=" + couponCount +
                ", coupons=" + coupons +
                ", transactionId='" + transactionId + '\'' +
                ", outTradeNo='" + outTradeNo + '\'' +
                ", attach='" + attach + '\'' +
                ", timeEnd='" + timeEnd + '\'' +
                ", tradeStateDesc='" + tradeStateDesc + '\'' +
                '}';
    }

    /**
     * 根据接口响应结果构建实例
     *
     * @param xml
     * @return
     */
    public static OrderQueryResponse build(String xml, String signKey) throws WXPayException {
        boolean signOk = false;
        try {
            signOk = WXPayUtil.isSignatureValid(xml, signKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!signOk) {
            throw new WXPayException(WXPayConstants.SIGNATURE_EXCEPTION);
        }

        Map<String, String> responseMap = null;
        try {
            responseMap = WXPayUtil.xmlToMap(xml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (responseMap == null) {
            return null;
        }

        OrderQueryResponse instance = new OrderQueryResponse();
        instance.setResultCode(responseMap.get("return_code"));
        instance.setReturnMsg(responseMap.get("return_msg"));
        instance.setAppId(responseMap.get("appid"));
        instance.setMchId(responseMap.get("mch_id"));
        instance.setNonceStr(responseMap.get("nonce_str"));
        instance.setSign(responseMap.get("sign"));
        instance.setResultCode(responseMap.get("result_code"));
        instance.setErrCode(responseMap.get("err_code"));
        instance.setTimeEnd(responseMap.get("err_code_des"));
        instance.setDeviceInfo(responseMap.get("device_info"));
        instance.setOpenId(responseMap.get("openid"));
        instance.setIsSubscribe(responseMap.get("is_subscribe"));
        instance.setTradeType(responseMap.get("trade_type"));
        instance.setTradeState(responseMap.get("trade_state"));
        instance.setBankType(responseMap.get("bank_type"));
        instance.setTotalFee(Integer.parseInt(responseMap.get("total_fee")));
        instance.setSettlementTotalFee(Integer.parseInt(responseMap.get("settlement_total_fee")));
        instance.setFeeType(responseMap.get("fee_type"));
        instance.setCashFee(Integer.parseInt(responseMap.get("cash_fee")));
        instance.setCashFeeType(responseMap.get("cash_fee_type"));
        instance.setCouponFee(Integer.parseInt(responseMap.get("coupon_fee")));
        instance.setCouponCount(Integer.parseInt(responseMap.get("coupon_count")));

        List<Coupon> coupons = new ArrayList<>();
        for (int i = 0; i < instance.getCouponCount(); i++) {
            Coupon coupon = new Coupon();
            coupon.setCouponId(responseMap.get("coupon_id_" + i));
            coupon.setCouponType(responseMap.get("coupon_type_" + i));
            coupon.setCouponFee(Integer.parseInt(responseMap.get("coupon_fee_" + i)));
            coupons.add(coupon);
        }
        instance.setCoupons(coupons);
        instance.setTransactionId(responseMap.get("transaction_id"));
        instance.setOutTradeNo(responseMap.get("out_trade_no"));
        instance.setAttach(responseMap.get("attach"));
        instance.setTimeEnd(responseMap.get("time_end"));
        instance.setTradeStateDesc(responseMap.get("trade_state_desc"));
        return instance;
    }
}
